/*******************************************************************************
 * Copyright (c) 2009 Ravenhearte Design.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 	*	Redistributions of source code must retain the above copyright
 * 		notice, this list of conditions and the following disclaimer.
 * 
 * 	*	Redistributions in binary form must reproduce the above copyright
 * 		notice, this list of conditions and the following disclaimer in the
 * 		documentation and/or other materials provided with the distribution.
 * 
 * 	*	Neither the name of 'Ravenhearte Design' nor the names of its contributors 
 * 		may be used to endorse or promote products derived from this software 
 * 		without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/

package org.ravenhearte.engine;

import org.ravenhearte.engine.input.EventHandler;
import org.ravenhearte.engine.input.InputEvent;
import org.ravenhearte.engine.input.InputEventManager;
import org.ravenhearte.engine.input.InputEvent.EventType;
import org.ravenhearte.engine.input.InputEventManager.Queue;
import org.ravenhearte.engine.modes.EditMode;
import org.ravenhearte.gameplay.concepts.locations.*;

import com.jme.app.BaseGame;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.Timer;

public class Engine extends BaseGame implements EventHandler {
	private int width, height, depth, freq;
	private boolean fullscreen;

	private InputEventManager eventManager;
	private GameMode mode;
	private World world;

	private Camera cam;

	protected Timer timer;

	public static void main(String[] args) {
		Engine engine = new Engine();
		engine.setConfigShowMode(ConfigShowMode.AlwaysShow, Engine.class
				.getClassLoader().getResource(
						"jmetest/data/images/FlagRush.png"));
		engine.start();
	}

	@Override
	protected void update(float interpolation) {
		timer.update();
		interpolation = timer.getTimePerFrame();
		mode.update(interpolation);
	}

	@Override
	protected void render(float interpolation) {
		display.getRenderer().clearBuffers();
		display.getRenderer().draw(mode.getNode());
		display.getRenderer().draw(mode.getGui().getNode());
	}

	@Override
	protected void initSystem() {
		width = this.settings.getWidth();
		height = this.settings.getHeight();
		depth = this.settings.getDepth();
		freq = this.settings.getFrequency();
		fullscreen = this.settings.isFullscreen();

		try {
			display = DisplaySystem.getDisplaySystem(this.getNewSettings()
					.getRenderer());
			display.createWindow(width, height, depth, freq, fullscreen);

			cam = display.getRenderer().createCamera(width, height);
		} catch (JmeException e) {
			e.printStackTrace();
			System.exit(1);
		}

		display.getRenderer().setBackgroundColor(ColorRGBA.black);

		cam.setFrustumPerspective(45.0f, (float) width / (float) height,
				1, 1000);

		timer = Timer.getTimer();

		display.getRenderer().setCamera(cam);

		eventManager = new InputEventManager();

		MouseInput.get().setCursorVisible(true);
	}

	@Override
	protected void initGame() {
		loadWorld();
		loadEvents();

		mode = new EditMode(world);
	}

	@Override
	protected void reinit() {
		display.recreateWindow(width, height, depth, freq, fullscreen);
	}

	@Override
	protected void cleanup() {
	}

	protected void loadWorld() {
		world = new World("Angrea");
		City city = new City("Fisherville");
		District district = new District("Fisherville Harbour");
		Building building = new Building("Stag and Doe Tavern");
		Room room = new Room("Stag and Doe Common Room");
		building.addRoom(room);
		district.addBuilding(building);
		city.addDistrict(district);
		world.addCity(city);
		world.setStartLocation(room);
	}

	private void loadEvents() {
		InputEvent evnt = new InputEvent();
		evnt.id = KeyInput.KEY_ESCAPE;
		evnt.parent = this;
		evnt.type = EventType.KEYUP;
		eventManager.registerEvent(Queue.GUI, evnt);
	}
	
	@Override
	public void unloadEvents() {
		
	}

	@Override
	public boolean onEvent(InputEvent ev) {
		switch (ev.type) {
		case KEYUP:
			switch (ev.id) {
			case KeyInput.KEY_ESCAPE:
				finished = true;
				return true;
			}
		}
		return false;
	}
}
